    /*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.click.app.webapp.action;

import com.click.app.model.Cart;
import com.click.app.model.EntryProductDetail;
import com.click.app.model.ProductType;
import com.click.app.model.FeatureProduct;
import com.click.app.model.FeatureProductName;
import com.click.app.model.LabelValue;
import com.click.app.model.Product;
import com.click.app.model.RequestClient;
import com.click.app.model.StorageProduct;
import com.click.app.model.User;
import com.click.app.service.CartManager;
import com.click.app.service.EntryProductDetailManager;
import com.click.app.service.FeatureProductManager;
import com.click.app.service.FeatureProductNameManager;
import com.click.app.service.ProductManager;
import com.click.app.service.ProductTypeManager;
import com.click.app.service.RequestClientManager;
import com.click.app.service.StorageProductManager;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;
import org.apache.struts2.ServletActionContext;

/**
 *
 * @author orgale
 */
public class ProductAction extends BaseAction {

    private ProductManager productManager;
    private ProductTypeManager productTypeManager;
    private RequestClientManager requestClientManager;
    //private GenericManager<PurchaseDetail, Long> purchaseDetailManager;
    private FeatureProductManager featureProductManager;
    private FeatureProductNameManager featureProductNameManager;
    private StorageProductManager storageProductManager;
    private EntryProductDetailManager entryProductDetailManager;
    private List products;
    private Product product;
    private Long id;
    private Long idMeasureUnit;
    private List<FeatureProduct> featureProductsDescriptions;
    private Long idD;
    private String featureProductName;
    private String featureProductDescription;
    private FeatureProduct featureProduct;
    private Integer featureProductIndex;
    private Long idFeatureProduct;
    private List<FeatureProduct> featureProductList;
    private List<FeatureProduct> featureProductsList;
    private String limit;
    private CartManager cartManager;
    private RequestClient requestClient;
    private File file;
    private String fileContentType;
    private String fileFileName;
    private String name;
    private InputStream inputStream;
    private Long idPt;
    private Long idProduct;

    public void setProductTypeManager(ProductTypeManager productTypeManager) {
        this.productTypeManager = productTypeManager;
    }

    public void setEntryProductDetailManager(EntryProductDetailManager entryProductDetailManager) {
        this.entryProductDetailManager = entryProductDetailManager;
    }

    public void setRequestClientManager(RequestClientManager requestClientManager) {
        this.requestClientManager = requestClientManager;
    }

    public void setCartManager(CartManager cartManager) {
        this.cartManager = cartManager;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Product getProduct() {
        return product;
    }

    public void setProduct(Product product) {
        this.product = product;
    }

    public List<ProductType> getProductTypes() {
        return productTypeManager.getAll();
    }

    public StorageProduct findStorageProduct(Product m) {
        for (StorageProduct st : storageProductManager.getAll()) {
            if (st.getProduct().equals(m)) {
                return st;
            }
        }
        return null;
    }

    public boolean entryProductDetailFree() {
        boolean resp = true;
        List<EntryProductDetail> pds = entryProductDetailManager.getAll();
        for (EntryProductDetail pd : pds) {
            if (pd.getProduct().equals(product)) {
                resp = false;
            }
        }
        return resp;
    }

    public String delete() {
        if (entryProductDetailFree()) {
            //update productType
            for (ProductType pt : productTypeManager.getAll()) {
                if (pt.getProducts().contains(productManager.get(product.getId()))) {
                    pt.getProducts().remove(productManager.get(product.getId()));
                }
                productTypeManager.save(pt);

            }
            //remove  product
            productManager.remove(product.getId());
            saveMessage(getText("product.deleted"));
        } else {
            errorMessage(getText("product.deleteError"));
        }
        return SUCCESS;
    }

    public String edit() throws Exception {
        System.out.println("Editing product...");

        if (id != null) {
            System.out.println("Editing existing product...");

            product = productManager.get(id);
            featureProductList = featureProductManager.findByProduct(product);
            getSession().setAttribute("product", product);
            getSession().setAttribute("featureProductList", featureProductList);
            getSession().setAttribute("deleteFeatureProductList", new ArrayList<FeatureProduct>());

        } else {
            System.out.println("Editing new product...");

            featureProductList = new ArrayList<FeatureProduct>();
            product = new Product();
            featureProduct = new FeatureProduct();
            getSession().setAttribute("product", null);
            getSession().setAttribute("featureProductList", featureProductList);
            getSession().setAttribute("deleteFeatureProducts", new ArrayList<FeatureProduct>());

        }
        getSession().setAttribute("featureProductList", featureProductList);
        System.out.println("productedited: " + product.getId());
        return SUCCESS;
    }

    public boolean haveCart(User user) {
        boolean resp = false;
        if (!cartManager.findCartByUser(user).isEmpty()) {
            resp = true;
        }
        return resp;
    }

    public String buy() {
        User u = userManager.getUserByUsername(getRequest().getRemoteUser());
        product = productManager.get(id);

        RequestClient rc = new RequestClient();

        rc.setDateRequestClient(new Date());
        rc.getProducts().add(product);
        rc.setPrice(productManager.getHighestPrice(product));
        rc.setQuantity(0.0f);
        return SUCCESS;
    }

    public String addToCart() {
        User u = userManager.getUserByUsername(getRequest().getRemoteUser());
        product = productManager.get(id);
        Cart cart;
        if (!haveCart(u)) {
            cart = new Cart();
            cart.setUser(u);
            cart = cartManager.save(cart);

        } else {
            cart = cartManager.findCartByUser(u).get(0);
        }

        RequestClient rc = new RequestClient();

        rc.setDateRequestClient(new Date());
        rc.setCart(cart);
        rc.setPrice(productManager.getHighestPrice(product));
        rc.getProducts().add(product);
        rc.setQuantity(1f);
        rc = requestClientManager.save(rc);



        cart.getRequests().add(rc);
        float tp = 0.0f;
        for (RequestClient p : cart.getRequests()) {
            tp = tp + (p.getPrice() * p.getQuantity());
        }
        cart.setTotalPrice(tp);
        System.out.println("cart total price..." + cart.getTotalPrice());
        cart = cartManager.save(cart);

        return SUCCESS;
    }

    public int findIndex(Long id) {
        int i = -1;
        featureProductList = (List<FeatureProduct>) getSession().getAttribute("featureProductList");
        for (FeatureProduct d : featureProductList) {
            if (d.getId().equals(id)) {
                i = featureProductList.indexOf(d);
            }
        }
        System.out.println("retornando index: " + i);
        return i;
    }

    public String deleteFeatureProduct() {
        featureProductList = (List<FeatureProduct>) getSession().getAttribute("featureProductList");
        featureProduct = featureProductList.get(findIndex(idFeatureProduct));
        if (featureProduct.getId() != null) {
            List<FeatureProduct> deleteFeatureProductList = (List<FeatureProduct>) getSession().getAttribute("deleteFeatureProductList");
            if (deleteFeatureProductList == null) {
                deleteFeatureProductList = new ArrayList<FeatureProduct>();
            }
            deleteFeatureProductList.add(featureProduct);
            getSession().setAttribute("deleteFeatureProductList", deleteFeatureProductList);
        }
        featureProductList.remove(featureProduct);
        getSession().setAttribute("featureProductList", featureProductList);

        featureProduct = new FeatureProduct();
        featureProductIndex = null;

        return SUCCESS;
    }

    public boolean featureProductExists(FeatureProduct di) {
        boolean exists = false;
        featureProductList = (List<FeatureProduct>) getSession().getAttribute("featureProductList");
        for (FeatureProduct d : featureProductList) {
            if ((d.getNameLang().matches(di.getNameLang())) && (d.getDescriptionLang().matches(di.getDescriptionLang()))) {
                exists = true;
            }
        }
        return exists;
    }

    public String saveFeatureProduct() {
        System.out.println("saving FeatureProduct ...");
        featureProduct = getFeatureProductWithNameAndDescription(getFeatureProductName(), getFeatureProductDescription());
System.out.println("fp: " + featureProduct);
        if (featureProductExists(featureProduct)) {
            System.out.println("featureProduct exists...");
        //errorMessage(getText("featureProduct.exists"));
        } else {
            featureProductList = (List<FeatureProduct>) getSession().getAttribute("featureProductList");
System.out.println("fpl: " + featureProductList);
            if (featureProductIndex == null) {
                featureProductList.add(featureProduct);
            //saveMessage(getText("featureProduct.added"));
            } else {
                featureProductList.set(featureProductIndex, featureProduct);
                featureProductIndex = null;
            //saveMessage(getText("featureProduct.updated"));
            }
            System.out.println("sar: " + featureProductList);
            getSession().setAttribute("featureProductList", featureProductList);
            featureProduct = new FeatureProduct();
        }
        return SUCCESS;
    }

    public String saveFeatureProducts() {
        product = (Product) getSession().getAttribute("product");
        System.out.println("saving FeatureProducts ...");
        System.out.println("current product: " + product);

        return SUCCESS;
    }

    public String manageFeatureProduct() {
        System.out.println("current product: " + product);
        getSession().setAttribute("product", product);
        return SUCCESS;
    }

    public String rdl() {
        System.out.println("probando la lista de featPrdList");
        featureProductList = (List<FeatureProduct>) getSession().getAttribute("featureProductList");

        return SUCCESS;
    }

    public List<LabelValue> getBooleans() {
        List<LabelValue> b = new ArrayList<LabelValue>();
        LabelValue t = new LabelValue(getText("true.available"), "true");
        LabelValue f = new LabelValue(getText("false.unavailable"), "false");
        b.add(t);
        b.add(f);
        return b;
    }

    public boolean validationPasses() {
        Float aux = 0.0f;
        boolean vp = true;
        if (product.getName() == null || product.getName().matches("")) {
            errorMessage("Required field, name.");
            vp = false;
        }
        if (product.getCode() == null || product.getCode().matches("")) {
            errorMessage("Required field, code.");
            vp = false;
        }
        if (product.getDescription() == null || product.getDescription().matches("")) {
            errorMessage("Required field, description.");
            vp = false;
        }

        if (product.getListFeatureProducts().isEmpty()) {
            errorMessage("Must asign at least one product feature.");
            vp = false;
        }

        return vp;
    }

    public String afp() {
        System.out.println("currentProduct: " + product);
        getSession().setAttribute("product", product);

        return "afp";
    }

    public String save() throws Exception {
        System.out.println("Saving product...");

        if (cancel != null) {
            System.out.println("currentProduct: " + product);
            getSession().setAttribute("product", product);
            return CANCEL;
        }

        if (delete != null) {
            return delete();
        }

        boolean isNew = (product.getId() == null);

        featureProductList = (List<FeatureProduct>) getSession().getAttribute("featureProductList");

        if (product.getListFeatureProducts() == null) {
            product.setListFeatureProducts(featureProductList);
        } else {
            product.getListFeatureProducts().addAll(featureProductList);
        }

        if (file == null) {
            String path = ServletActionContext.getServletContext().getRealPath("/images");
            file = new File(path + "/403.jpg");
        }
        InputStream is = new FileInputStream(file);
        long length = file.length();
        if (length > Integer.MAX_VALUE) {
            // File is too large
        }
        byte[] bytes = new byte[(int) length];
        int offset = 0;
        int numRead = 0;
        while (offset < bytes.length && (numRead = is.read(bytes, offset, bytes.length - offset)) >= 0) {
            offset += numRead;
        }
        if (offset < bytes.length) {
            throw new IOException("Could not completely read file " + file.getName());
        }
        is.close();
        product.setImageProduct(bytes);

        if (validationPasses()) {
            //product.setImageProduct(null);
            product = productManager.save(product);
        } else {
            return ERROR;
        }
        StorageProduct sm = new StorageProduct();
        if (isNew) {
            sm.setProduct(product);
            sm.setStock(new Integer(0));
        } else {
            sm = storageProductManager.findByIdProduct(product.getId()).get(0);
        }
        sm = storageProductManager.save(sm);
        String key = (isNew) ? "product.added" : "product.updated";
        saveMessage(getText(key));

        if (!isNew) {
            return INPUT;
        } else {
            return SUCCESS;
        }
    }

    public void setProductManager(ProductManager productManager) {
        this.productManager = productManager;
    }

    public void setFeatureProductManager(FeatureProductManager featureProductManager) {
        this.featureProductManager = featureProductManager;
    }

    public void setFeatureProductNameManager(FeatureProductNameManager featureProductNameManager) {
        this.featureProductNameManager = featureProductNameManager;
    }

    public void setStorageProductManager(StorageProductManager storageProductManager) {
        this.storageProductManager = storageProductManager;
    }

    public List getProducts() {
        return products;
    }

    public String list() {
        System.out.println("ProductAction -> list()");
        getSession().setAttribute("product", null);
        products = productManager.getAllPrices();
        System.out.println("ProductAction -> end list()");
        return SUCCESS;
    }

    public InputStream getInputStream() {
        System.out.println("ProductAction -> getInputStream() :--> " + id + " - " + idProduct);
        inputStream = null;
        //getResponse().resetBuffer();
        //getResponse().reset();
        if (id != null) {
            product = productManager.get(id);
        }

        if (idPt != null) {
            product = productManager.get(idPt);
        }

        if (getSession().getAttribute("product") != null) {
            product = (Product) getSession().getAttribute("product");
        }

        if (product != null && product.getImageProduct() != null) {
            inputStream = new ByteArrayInputStream(product.getImageProduct());
        } else {
            if (product != null && product.getImageProduct() == null) {

                try {
                    String path = ServletActionContext.getServletContext().getRealPath("/images");
                    file = new File(path + "/403.jpg");
                    InputStream is = new FileInputStream(file);
                    long length = file.length();
                    if (length > Integer.MAX_VALUE) {
                        // File is too large
                    }

                    byte[] bytes = new byte[(int) length];
                    int offset = 0;
                    int numRead = 0;
                    while (offset < bytes.length && (numRead = is.read(bytes, offset, bytes.length - offset)) >= 0) {
                        offset += numRead;
                    }
                    if (offset < bytes.length) {
                        throw new IOException("Could not completely read file " + file.getName());
                    }
                    is.close();
                    inputStream = new ByteArrayInputStream(bytes);
                } catch (IOException ioex) {
                    ioex.printStackTrace();
                }
            }
        }
        System.out.println("ProductAction -> end getInputStream()");
        return inputStream;
    }

    public void setInputStream(InputStream inputStream) {
        this.inputStream = inputStream;
    }

    public List<Product> getFullProducts() {
        List<Product> all = productManager.getAll();
        for (Product m : all) {
            for (FeatureProduct d : m.getListFeatureProducts()) {
                m.setName(m.getName() + " " + d.getDescription());
            }
        }
        return all;
    }

    /**
     * @return the idMeasureUnit
     */
    public Long getIdMeasureUnit() {
        return idMeasureUnit;
    }

    /**
     * @param idMeasureUnit the idMeasureUnit to set
     */
    public void setIdMeasureUnit(Long idMeasureUnit) {
        this.idMeasureUnit = idMeasureUnit;
    }

    /**
     * @return the featureProduct
     */
    public FeatureProduct getFeatureProduct() {
        return featureProduct;
    }

    /**
     * @param featureProduct the featureProduct to set
     */
    public void setFeatureProduct(FeatureProduct featureProduct) {
        this.featureProduct = featureProduct;
    }

    /**
     * @return the featureProductIndex
     */
    public Integer getFeatureProductIndex() {
        return featureProductIndex;
    }

    /**
     * @param featureProductIndex the featureProductIndex to set
     */
    public void setFeatureProductIndex(Integer featureProductIndex) {
        this.featureProductIndex = featureProductIndex;
    }
    private String lst;
    private List lstList = null;
    private List lstList2 = null;

    public List getLstList() {
        System.out.println("Obteining list");
        System.out.println("LIST: " + lstList);
        return lstList;
    }

    public void setLstList(List lstList) {
        this.lstList = lstList;
    }

    public String getLst() {
        return lst;
    }

    public void setLst(String lst) {
        this.lst = lst;
    }

    public List<FeatureProduct> getFeatureProductList() {
        return (List<FeatureProduct>) getSession().getAttribute("featureProductList");
    }

    public List<FeatureProduct> getFeatureProductsList() {
        return featureProductManager.findFeatureProducts();
    }

    /**
     * @return the idD
     */
    public Long getIdD() {
        return idD;
    }

    /**
     * @param idD the idD to set
     */
    public void setIdD(Long idD) {
        this.idD = idD;
    }
    private List characters;

    public String ajaxSelect() {

        System.out.println("EXECUTE!!!");

        idD = Long.parseLong(getRequest().getParameter("idD"));

        System.out.println("idD: " + idD);

        FeatureProduct dis = featureProductManager.get(idD);
        if (dis == null) {
            dis = new FeatureProduct();
        }
        featureProductsDescriptions = featureProductManager.findFeatureProductsName(dis.getName());
        System.out.println("featureProduct descriptions: " + featureProductsDescriptions.size());
        getSession().setAttribute("featureProductDescriptions", featureProductsDescriptions);
        return SUCCESS;
    }

    public String ajaxS() {
        // Get a list of characters associated with the select TV show

        System.out.println("EXECUTE!!!");

        idD = Long.parseLong(getRequest().getParameter("idD"));

        System.out.println("idD: " + idD);

        FeatureProduct dis = featureProductManager.get(idD);
        if (dis == null) {
            dis = new FeatureProduct();
        }
        featureProductsDescriptions = featureProductManager.findFeatureProductsName(dis.getName());
        return SUCCESS;
    }

    // End execute()
    // This method returns a list of characters for a given TV show.  If no TV
    // show is selected, i.e., initial page view, am empty ArrayList is returned.
    /**
     * @return the characters
     */
    public List getCharacters() {
        System.out.print("getting characters...");
        return characters;
    }

    /**
     * @param characters the characters to set
     */
    public void setCharacters(List characters) {
        this.characters = characters;
    }

    /**
     * @return the featureProductsDescription
     */
    public List<FeatureProduct> getFeatureProductsDescriptions() {
        return featureProductsDescriptions;
    }

    /**
     * @param featureProductsDescription the featureProductsDescription to set
     */
    public void setFeatureProductsDescriptions(List<FeatureProduct> featureProductsDescription) {
        this.featureProductsDescriptions = featureProductsDescription;
    }

    /**
     * @param featureProductList the featureProductList to set
     */
    public void setFeatureProductList(List<FeatureProduct> featureProductList) {
        this.featureProductList = featureProductList;
    }

    /**
     * @return the featureProductDescription
     */
    public String getFeatureProductDescription() {
        return featureProductDescription;
    }

    /**
     * @param featureProductDescription the featureProductDescription to set
     */
    public void setFeatureProductDescription(String featureProductDescription) {
        this.featureProductDescription = featureProductDescription;
    }

    /**
     * @param featureProductsList the featureProductsList to set
     */
    public void setFeatureProductsList(List<FeatureProduct> featureProductsList) {
        this.featureProductsList = featureProductsList;
    }

    /**
     * @return the idFeatureProduct
     */
    public Long getIdFeatureProduct() {
        return idFeatureProduct;
    }

    /**
     * @param idFeatureProduct the idFeatureProduct to set
     */
    public void setIdFeatureProduct(Long idFeatureProduct) {
        this.idFeatureProduct = idFeatureProduct;
    }

    public String helpList() {
        return SUCCESS;
    }

    public String help() {
        return SUCCESS;
    }

    /**
     * @return the limit
     */
    public String getLimit() {
        System.out.println("limitg: " + limit);
        return limit;
    }
    private String defaultItem;
    private String doubleDefaultItem;

    /**
     * @param limit the limit to set
     */
    public void setLimit(String limit) {
        this.limit = limit;
    }

    /**
     * @return the featureProductName
     */
    public String getFeatureProductName() {
        return featureProductName;
    }

    /**
     * @param featureProductName the featureProductName to set
     */
    public void setFeatureProductName(String featureProductName) {
        this.featureProductName = featureProductName;
    }

    public List<FeatureProductName> getFeatureProductNames() {
        return featureProductNameManager.getAll();
    }

    /**
     * @return the defaultItem
     */
    public String getDefaultItem() {
        return defaultItem;
    }

    /**
     * @param defaultItem the defaultItem to set
     */
    public void setDefaultItem(String defaultItem) {
        this.defaultItem = defaultItem;
    }

    /**
     * @return the doubleDefaultItem
     */
    public String getDoubleDefaultItem() {
        return doubleDefaultItem;
    }

    /**
     * @param doubleDefaultItem the doubleDefaultItem to set
     */
    public void setDoubleDefaultItem(String doubleDefaultItem) {
        this.doubleDefaultItem = doubleDefaultItem;
    }

    public FeatureProduct getFeatureProductWithNameAndDescription(String n, String v) {

        FeatureProduct d = null;
        for (FeatureProduct di : featureProductManager.getAll()) {
            if (di.getDescription().matches(v) || di.getDescriptionEs().matches(v)) {
                System.out.println("sar1:|"+di.getNameLang()+"|");
                System.out.println("sar1:|"+n+"|");

                if (di.getName().matches(n) || di.getNameEs().matches(n)) {
                    System.out.println("enter if2... :");
                    d = di;
                }
            }
        }
        return d;
    }

    public File getFile() {
        return file;
    }

    public void setFile(File file) {
        this.file = file;
    }

    public String getFileContentType() {
        return fileContentType;
    }

    public void setFileContentType(String fileContentType) {
        this.fileContentType = fileContentType;
    }

    public String getFileFileName() {
        return fileFileName;
    }

    public void setFileFileName(String fileFileName) {
        this.fileFileName = fileFileName;
    }

    public List getLstList2() {
        return lstList2;
    }

    public void setLstList2(List lstList2) {
        this.lstList2 = lstList2;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    /**
     * @return the requestClient
     */
    public RequestClient getRequestClient() {
        return requestClient;
    }

    /**
     * @param requestClient the requestClient to set
     */
    public void setRequestClient(RequestClient requestClient) {
        this.requestClient = requestClient;
    }

    public Long getIdPt() {
        return idPt;
    }

    public void setIdPt(Long idPt) {
        this.idPt = idPt;
    }

    public Long getId() {
        return id;
    }

    public Long getIdProduct() {
        return idProduct;
    }

    public void setIdProduct(Long idProduct) {
        this.idProduct = idProduct;
    }
}
